package cn.stylefeng.guns.modular.info.service;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import cn.stylefeng.guns.base.pojo.page.LayuiPageFactory;
import cn.stylefeng.guns.base.pojo.page.LayuiPageInfo;
import cn.stylefeng.guns.base.utils.FootDateUtil;
import cn.stylefeng.guns.constant.Constant;
import cn.stylefeng.guns.modular.info.entity.Game;
import cn.stylefeng.guns.modular.info.entity.LeagueTeam;
import cn.stylefeng.guns.modular.info.entity.Season;
import cn.stylefeng.guns.modular.info.mapper.GameMapper;
import cn.stylefeng.guns.modular.info.mapper.SeasonMapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Sheet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;

/**
 * @program: guns-vip
 * @description:
 * @author: xiesm
 * @create: 2019-12-30 17:57
 **/
@Service
public class GameService extends ServiceImpl<GameMapper, Game> {

    @Autowired
    private TeamService teamService;
    @Autowired(required = false)
    private GameMapper gameMapper;
    @Autowired(required = false)
    private SeasonMapper seasonMapper;

    public LayuiPageInfo findGameList(Map<String, String> param) {
        Map<Integer, String> teamMap = teamService.findTeamMap();
        Page page = LayuiPageFactory.defaultPage();

        IPage iPage = this.gameMapper.findGameByParam(page, param);
        for (int i = 0; i < iPage.getRecords().size(); i++) {
            Game res = (Game) iPage.getRecords().get(i);
            res.setTeamAName(teamMap.get(res.getFkTeamAId()));
            res.setTeamBName(teamMap.get(res.getFkTeamBId()));
            Date date = res.getDate();
//            String[] dates = date.split(",");
//            String str = "%s-%s-%s %s:%s";
//            res.setDate(String.format(str, dates[0], dates[1], dates[2], dates[3], dates[4]));
        }
        return LayuiPageFactory.createPageInfo(iPage);
    }

    public List<Season> getYear(String fkLeagueId) {
        List<Season> seasons = seasonMapper.selectList(new QueryWrapper<Season>().eq("fk_league_id", fkLeagueId).orderByDesc("priority"));
        return seasons;
    }


    public String getRunCount(String fkLeagueId) {
        Integer[] nums = new Integer[7];
        Integer[] counts = {1, 2, 3, 5, 10, 20, 40};
        Integer num = baseMapper.groupGameRunCount(fkLeagueId);
        if (num != null) {
            for (int i = 0; i < nums.length; i++) {
                nums[i] = num * counts[i];
            }
        }
        return StringUtils.join(nums, ",");
    }

    public String setScore() {
        List<Game> games = gameMapper.selectList(null);
        games.stream().forEach(game -> {
            if (game.getScore() != null) {
                if (game.getFirstHalfA() == null || game.getFirstHalfB() == null ||
                        game.getSecondHalfA() == null || game.getSecondHalfB() == null) {
                    String[] scores = game.getScore().split("\\(");

                    //0-13(0-4)
                    String[] score1 = scores[0].split("-"); //0,13
                    String[] score2 = scores[1].replace(")", "").split("-"); // 0,4

                    game.setFirstHalfA(Integer.valueOf(score2[0]));
                    game.setFirstHalfB(Integer.valueOf(score2[1]));
                    game.setSecondHalfA(Integer.valueOf(score1[0]) - game.getFirstHalfA());
                    game.setSecondHalfB(Integer.valueOf(score1[1]) - game.getFirstHalfB());
                    gameMapper.updateById(game);
                }
            }
        });
        return "ok";
    }

    private void getNextWeekGame(Map<String, List<Game>> map, Integer teamId, int week, int year) {
        QueryWrapper<Game> gameWrapper2 = new QueryWrapper<>();
        gameWrapper2.between("date", FootDateUtil.getWeekMonday(week, year), FootDateUtil.getWeekSunday(week, year));
        gameWrapper2.and(wrapper -> wrapper.eq("fk_teamA_id", teamId).or().eq("fk_teamB_id", teamId));
        List<Game> games = gameMapper.selectList(gameWrapper2);
        games.stream().forEach(game -> {
            if (map.get(game.getFkLeagueId()) != null) {
                map.get(game.getFkLeagueId()).add(game);
            } else {
                map.put(game.getFkLeagueId(), new ArrayList<Game>() {{
                    add(game);
                }});
            }
        });
    }

    public void getGameData(String date, String endData, ExcelWriter writer) {
        if (endData != null) {
            String year = date.substring(0, 4);

            DateTime time = DateUtil.parse(date);
            DateTime endTime = DateUtil.parse(endData);

            int week1 = DateUtil.weekOfYear(time);
            int week2 = DateUtil.weekOfYear(endTime);
            for (; week1 <= week2; week1++) {
                List<LeagueTeam> leagueTeams = getLeagueTeam(week1, Integer.valueOf(year));
                leagueTeams.sort((o1, o2) -> (int) (o1.getDate().getTime() - o2.getDate().getTime()));
                writer.write(leagueTeams, true);
            }
        } else {
            String year = date.substring(0, 4);
            DateTime time = DateUtil.parse(date);
            int week = DateUtil.weekOfYear(time);
            List<LeagueTeam> leagueTeams = getLeagueTeam(week, Integer.valueOf(year));
            leagueTeams.sort((o1, o2) -> (int) (o1.getDate().getTime() - o2.getDate().getTime()));
            writer.write(leagueTeams);
        }
    }

    public List<LeagueTeam> getLeagueTeam(int week, Integer year) {
        List<LeagueTeam> leagueTeams = new ArrayList<>();
        //查询上周乌龙球数据
        QueryWrapper<Game> gameWrapper = new QueryWrapper<>();
        gameWrapper.between("date", FootDateUtil.getWeekMonday(week - 2, year), FootDateUtil.getWeekSunday(week - 2, year));
        gameWrapper.and(wrapper -> wrapper.eq("own_goal_teamA", "1").or().eq("own_goal_teamB", "1"));
        gameWrapper.orderByAsc("date");
        List<Game> games = gameMapper.selectList(gameWrapper);

        List<Integer> ownTeamIds = new ArrayList<>();

        Map<String, List<Game>> map = new HashMap<>();
        //遍历获取上周乌龙球球队本周赛程，包含主队和客队
        games.stream().forEach(game -> {
            if (game.getOwnGoalTeamA()) {
                ownTeamIds.add(game.getFkTeamBId());
                getNextWeekGame(map, game.getFkTeamBId(), week - 1, year);
            }
            if (game.getOwnGoalTeamB()) {
                ownTeamIds.add(game.getFkTeamAId());
                getNextWeekGame(map, game.getFkTeamAId(), week - 1, year);
            }
        });
        Set<Integer> set = new HashSet<>();

        //输出excel表格
        map.keySet().stream().forEach(k -> {
            List<Game> gameList = map.get(k);
            gameList.stream().forEach(game -> {
                LeagueTeam leagueTeam = new LeagueTeam();
                leagueTeam.setLeagueName(Constant.leagues.get(Integer.valueOf(game.getFkLeagueId())));
                leagueTeam.setTeamAName(Constant.teamIdDict.get(Integer.valueOf(game.getFkTeamAId())));
                leagueTeam.setTeamBName(Constant.teamIdDict.get(Integer.valueOf(game.getFkTeamBId())));
                leagueTeam.setDate(game.getDate());
                if (ownTeamIds.contains(game.getFkTeamAId())) {
                    leagueTeam.setOwnGoalA(String.valueOf(true));
                }
                if (ownTeamIds.contains(game.getFkTeamBId())) {
                    leagueTeam.setOwnGoalB(String.valueOf(true));
                }
                if (set.add(game.getId())) {
                    leagueTeams.add(leagueTeam);
                }
                if (game.getScore() != null) {
                    if (game.getOwnGoalTeamA() || game.getOwnGoalTeamB()) {
                        leagueTeam.setResultHasOwnGoal(String.valueOf(true));
                    }
                    if (!game.getOwnGoalTeamA() && !game.getOwnGoalTeamB()) {
                        leagueTeam.setResultHasOwnGoal(String.valueOf(false));
                    }
                }
            });
        });
        return leagueTeams;
    }

    public void getSeason(HttpServletResponse response, String date, String endDate) {
        ExcelWriter writer = ExcelUtil.getWriter();
        writer.addHeaderAlias("leagueName", "联赛");
        writer.addHeaderAlias("TeamAName", "主队");
        writer.addHeaderAlias("TeamBName", "客队");
        writer.addHeaderAlias("OwnGoalA", "主队乌龙");
        writer.addHeaderAlias("OwnGoalB", "客队乌龙");
        writer.addHeaderAlias("date", "日期");
        writer.addHeaderAlias("resultHasOwnGoal", "结果");

        getGameData(date, endDate, writer);
        setSizeColumn(writer.getSheet());

        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + System.currentTimeMillis() + ".xls");
        ServletOutputStream out = null;
        try {
            out = response.getOutputStream();
            writer.flush(out, true);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            writer.close();
        }
        IoUtil.close(out);
    }

    /**
     * 获取上周周一（第一天是周一）
     *
     * @return
     */
    public static Date getPreviousMonday(int num) {
        Calendar cal = Calendar.getInstance();
        // 将每周第一天设为星期一，默认是星期天
        cal.setFirstDayOfWeek(Calendar.MONDAY);
        cal.add(Calendar.DATE, num * 7);
        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);

        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }

    /**
     * 获取上周周日（第一天是周一）
     *
     * @return
     */
    public static Date getSunday(int num) {
        Calendar cal = Calendar.getInstance();
        //将每周第一天设为星期一，默认是星期天
        cal.setFirstDayOfWeek(Calendar.MONDAY);
        cal.add(Calendar.DATE, num * 7);
        cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);

        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        cal.set(Calendar.MILLISECOND, 999);
        return cal.getTime();
    }

    /**
     * 自适应宽度(中文支持)
     *
     * @param sheet
     */
    public static void setSizeColumn(Sheet sheet) {
        short cellNum = sheet.getRow(0).getLastCellNum();
        for (int i = 0; i < cellNum; i++) {
            sheet.autoSizeColumn(i);
            sheet.setColumnWidth(i, sheet.getColumnWidth(i) * 17 / 10);
        }
    }

}
